// Copyright (C) Kumo inc. and its affiliates.
// Author: Jeff.li lijippy@163.com
// All rights reserved.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.
//

#pragma once

#include <turbo/utility/status.h>
#include <cantor/proto/parser/ast.pb.h>

namespace cantor::resolved {
    class ResolvedContext;

    class PassBase {
    public:
        virtual ~PassBase() = default;

        /////////////////////////////////////////////////////////////////////////////////////////
        /// public api
        /////////////////////////////////////////////////////////////////////////////////////////

        virtual std::string name() const = 0;

        /////////////////////////////////////////////////////////////////////////////////////////
        /// stmts nodes
        /////////////////////////////////////////////////////////////////////////////////////////
        /// type
        virtual turbo::Result<bool> visit(cantor::pb::ast::TypeStmt &stmt) {
            return turbo::unimplemented_error("not implemented");
        }


        virtual turbo::Result<bool> visit(cantor::pb::ast::StartTxnStmt &stmt) {
            return turbo::unimplemented_error("not implemented");
        }


        virtual turbo::Result<bool> visit(cantor::pb::ast::CommitTxnStmt &stmt) {
            return turbo::unimplemented_error("not implemented");
        }


        virtual turbo::Result<bool> visit(cantor::pb::ast::RollbackTxnStmt &stmt) {
            return turbo::unimplemented_error("not implemented");
        }


        virtual turbo::Result<bool> visit(cantor::pb::ast::PragmaSetStmt &stmt) {
            return turbo::unimplemented_error("not implemented");
        }

        virtual turbo::Result<bool> visit(cantor::pb::ast::NewPrepareStmt &stmt){
            return turbo::unimplemented_error("not implemented");
        }


        virtual turbo::Result<bool> visit(cantor::pb::ast::ExecPrepareStmt &stmt) {
            return turbo::unimplemented_error("not implemented");
        }


        virtual turbo::Result<bool> visit(cantor::pb::ast::DeallocPrepareStmt &stmt) {
            return turbo::unimplemented_error("not implemented");
        }


        virtual turbo::Result<bool> visit(cantor::pb::ast::KillStmt &stmt) {
            return turbo::unimplemented_error("not implemented");
        }


        virtual turbo::Result<bool> visit(cantor::pb::ast::CreateNamespaceStmt &stmt) {
            return turbo::unimplemented_error("not implemented");
        }


        virtual turbo::Result<bool> visit(cantor::pb::ast::DropNamespaceStmt &stmt) {
            return turbo::unimplemented_error("not implemented");
        }


        virtual turbo::Result<bool> visit(cantor::pb::ast::AlterNamespaceStmt &stmt) {
            return turbo::unimplemented_error("not implemented");
        }


        virtual turbo::Result<bool> visit(cantor::pb::ast::CreateUserStmt &stmt) {
            return turbo::unimplemented_error("not implemented");
        }


        virtual turbo::Result<bool> visit(cantor::pb::ast::DropUserStmt &stmt) {
            return turbo::unimplemented_error("not implemented");
        }

        virtual turbo::Result<bool> visit(cantor::pb::ast::AlterUserStmt &stmt) {
            return turbo::unimplemented_error("not implemented");
        }

        virtual turbo::Result<bool> visit(cantor::pb::ast::InsertStmt &stmt) {
            return turbo::unimplemented_error("not implemented");
        }


        virtual turbo::Result<bool> visit(cantor::pb::ast::UpdateStmt &stmt) {
            return turbo::unimplemented_error("not implemented");
        }


        virtual turbo::Result<bool> visit(cantor::pb::ast::TruncateStmt &stmt) {
            return turbo::unimplemented_error("not implemented");
        }


        virtual turbo::Result<bool> visit(cantor::pb::ast::DeleteStmt &stmt) {
            return turbo::unimplemented_error("not implemented");
        }


        virtual turbo::Result<bool> visit(cantor::pb::ast::SelectStmt &stmt) {
            return turbo::unimplemented_error("not implemented");
        }


        virtual turbo::Result<bool> visit(cantor::pb::ast::UnionStmt &stmt) {
            return turbo::unimplemented_error("not implemented");
        }

        virtual turbo::Result<bool> visit(cantor::pb::ast::CreateTableStmt &stmt) {
            return turbo::unimplemented_error("not implemented");
        }


        virtual turbo::Result<bool> visit(cantor::pb::ast::DropTableStmt &stmt) {
            return turbo::unimplemented_error("not implemented");
        }


        virtual turbo::Result<bool> visit(cantor::pb::ast::CreateViewStmt &stmt) {
            return turbo::unimplemented_error("not implemented");
        }


        virtual turbo::Result<bool> visit(cantor::pb::ast::DropViewStmt &stmt) {
            return turbo::unimplemented_error("not implemented");
        }


        virtual turbo::Result<bool> visit(cantor::pb::ast::CreateDatabaseStmt &stmt) {
            return turbo::unimplemented_error("not implemented");
        }


        virtual turbo::Result<bool> visit(cantor::pb::ast::DropDatabaseStmt &stmt){
            return turbo::unimplemented_error("not implemented");
        }


        virtual turbo::Result<bool> visit(cantor::pb::ast::AlterTableStmt &stmt){
            return turbo::unimplemented_error("not implemented");
        }


        virtual turbo::Result<bool> visit(cantor::pb::ast::AlterViewStmt &stmt) {
            return turbo::unimplemented_error("not implemented");
        }


        virtual turbo::Result<bool> visit(cantor::pb::ast::ExplainStmt &stmt){
            return turbo::unimplemented_error("not implemented");
        }


        virtual turbo::Result<bool> visit(cantor::pb::ast::LoadDataStmt &stmt) {
            return turbo::unimplemented_error("not implemented");
        }


        virtual turbo::Result<bool> visit(cantor::pb::ast::GrantStmt &stmt) {
            return turbo::unimplemented_error("not implemented");
        }


        virtual turbo::Result<bool> visit(cantor::pb::ast::RevokeStmt &stmt) {
            return turbo::unimplemented_error("not implemented");
        }


        virtual turbo::Result<bool> visit(cantor::pb::ast::RestoreTableStmt &stmt) {
            return turbo::unimplemented_error("not implemented");
        }


        /////////////////////////////////////////////////////////////////////////////////////////
        /// expression nodes
        /////////////////////////////////////////////////////////////////////////////////////////
        /// var assign
        virtual turbo::Result<bool> pre_visit(cantor::pb::ast::VarAssign &node) = 0;

        virtual turbo::Result<bool> post_visit(cantor::pb::ast::VarAssign &node) = 0;

        virtual turbo::Result<bool> pre_visit(cantor::pb::ast::DispatchExpr &node) {
            return true;
        }

        virtual turbo::Result<bool> post_visit(cantor::pb::ast::DispatchExpr &node) {
            return true;
        }

    public:
        ResolvedContext *context{nullptr};
    };
} // namespace cantor::resolved
